// 判断是否是原生标签还是自定组件
function isReservedTag(tag) {
  return ["a", "div", "span", "button", "ul", "li", "h1", "h2", "h3", "h4", "h5", "h6"].includes(
    tag
  )
}

// 创建一个元素/组件节点
export function createElementNode(vm, tag, data = {}, ...children) {
  data = data == null ? {} : data

  // 是不是原生标签
  if (isReservedTag(tag)) {
    return vnode(vm, tag, data.key, data, children)
  } else {
    // 获取组件的构造函数
    let Ctor = vm.$options.components[tag]
    // 创建一个组件的虚拟节点
    return createComponentNode(vm, tag, data.key, data, children, Ctor)
  }
}

// Ctor 可能是个对象/函数
function createComponentNode(vm, tag, key, data, children, Ctor) {
  if (typeof Ctor === "object") {
    Ctor = vm.$options._base.extend(Ctor)
  }
  data.hook = {
    init(vnode) {
      let instance = (vnode.componentInstance = new vnode.componentOptions.Ctor())
      instance.$mount()
    }
  }

  return vnode(vm, tag, key, data, children, null, { Ctor })
}

// 创建文本节点
export function createTextNode(vm, text) {
  return vnode(vm, undefined, undefined, undefined, undefined, text)
}

// 创建节点
function vnode(vm, tag, key, data, children, text, componentOptions) {
  return {
    vm,
    tag,
    key,
    data,
    children,
    text,
    componentOptions
  }
}
